package com.example.computer_exam_training_sys.service.impl;

import com.example.computer_exam_training_sys.dto.MessageDTO;
import com.example.computer_exam_training_sys.entity.UserMessage;
import com.example.computer_exam_training_sys.mapper.UserMessageMapper;
import com.example.computer_exam_training_sys.service.UserMessageService;
import com.example.computer_exam_training_sys.vo.MessageVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserMessageServiceImpl implements UserMessageService {

    private final UserMessageMapper userMessageMapper;

    public UserMessageServiceImpl(UserMessageMapper userMessageMapper) {
        this.userMessageMapper = userMessageMapper;
    }

    @Override
    @Transactional
    public MessageVO createMessage(Long senderId, MessageDTO messageDTO) {
        UserMessage message = new UserMessage();
        BeanUtils.copyProperties(messageDTO, message);
        message.setSenderId(senderId);
        message.setCreateTime(LocalDateTime.now());
        message.setUpdateTime(LocalDateTime.now());
        
        userMessageMapper.insert(message);
        return convertToVO(message);
    }

    @Override
    public MessageVO getMessageById(Long messageId, Long userId) {
        UserMessage message = userMessageMapper.findById(messageId);
        if (message == null) {
            return null;
        }
        // 检查权限：只有发送者、接收者或管理员可以查看消息
        if (!message.getSenderId().equals(userId) && 
            !message.getReceiverId().equals(userId)) {
            return null;
        }
        return convertToVO(message);
    }

    @Override
    public List<MessageVO> getReceivedMessages(Long userId) {
        List<UserMessage> messages = userMessageMapper.findByReceiverId(userId);
        return messages.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MessageVO> getSentMessages(Long userId) {
        List<UserMessage> messages = userMessageMapper.findBySenderId(userId);
        return messages.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<MessageVO> getPublishedMessages(String messageType, Long userId) {
        List<UserMessage> messages = userMessageMapper.findPublishedMessages(messageType, userId);
        return messages.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public int getPendingMessageCount(Long userId) {
        return userMessageMapper.countPendingMessages(userId);
    }

    @Override
    @Transactional
    public void updateMessageStatus(Long messageId, String status, Long userId) {
        UserMessage message = userMessageMapper.findById(messageId);
        if (message != null && message.getReceiverId().equals(userId)) {
            userMessageMapper.updateStatus(messageId, status);
        }
    }

    @Override
    @Transactional
    public MessageVO updateMessage(Long messageId, MessageDTO messageDTO, Long userId) {
        UserMessage message = userMessageMapper.findById(messageId);
        if (message == null || !message.getSenderId().equals(userId)) {
            return null;
        }
        
        BeanUtils.copyProperties(messageDTO, message);
        message.setUpdateTime(LocalDateTime.now());
        
        userMessageMapper.update(message);
        return convertToVO(message);
    }

    @Override
    @Transactional
    public void deleteMessage(Long messageId, Long userId) {
        UserMessage message = userMessageMapper.findById(messageId);
        if (message != null && 
            (message.getSenderId().equals(userId) || message.getReceiverId().equals(userId))) {
            userMessageMapper.delete(messageId);
        }
    }

    @Override
    @Transactional
    public MessageVO createShareNoteMessage(Long senderId, Long receiverId, Long noteId) {
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setReceiverId(receiverId);
        messageDTO.setMessageType("SHARE_NOTE");
        messageDTO.setNoteId(noteId);
        messageDTO.setTitle("笔记分享通知");
        messageDTO.setContent("分享了一个笔记给你");
        messageDTO.setStatus("PENDING");
        messageDTO.setPriority(2); // 设置中等优先级
        
        return createMessage(senderId, messageDTO);
    }

    @Override
    @Transactional
    public MessageVO createAnnouncement(Long senderId, MessageDTO messageDTO) {
        messageDTO.setMessageType("ANNOUNCEMENT");
        messageDTO.setStatus("PUBLISHED");
        messageDTO.setPublishTime(LocalDateTime.now());
        
        return createMessage(senderId, messageDTO);
    }

    @Override
    @Transactional
    public MessageVO createCourseNotice(Long senderId, Long courseId, MessageDTO messageDTO) {
        messageDTO.setMessageType("COURSE_NOTICE");
        messageDTO.setCourseId(courseId);
        messageDTO.setStatus("PUBLISHED");
        messageDTO.setPublishTime(LocalDateTime.now());
        
        return createMessage(senderId, messageDTO);
    }

    @Override
    public int getUnreadMessageCount(Long userId) {
        return userMessageMapper.countUnreadMessages(userId);
    }

    @Override
    public List<MessageVO> getAllMessages(Long adminId, String messageType) {
        List<UserMessage> messages = userMessageMapper.findAllMessages(adminId, messageType);
        return messages.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    private MessageVO convertToVO(UserMessage message) {
        MessageVO vo = new MessageVO();
        BeanUtils.copyProperties(message, vo);
        return vo;
    }

    private MessageDTO convertToDTO(UserMessage message) {
        MessageDTO dto = new MessageDTO();
        BeanUtils.copyProperties(message, dto);
        // 确保关联字段正确设置
        dto.setSenderName(message.getSenderName());
        dto.setReceiverName(message.getReceiverName());
        dto.setCourseName(message.getCourseName());
        dto.setNoteTitle(message.getNoteTitle());
        return dto;
    }
} 